import * as Matter from 'matter-js'
import { PixiApp } from '@/config/pixiApp.js'

export class RigidBodyRender {
  static getInstance(CONFIG_SIZE) {
    if (!this.instance) {
      this.instance = new RigidBodyRender(CONFIG_SIZE)
    }
    return this.instance
  }
  constructor(CONFIG_SIZE) {
    this.CONFIG_SIZE = CONFIG_SIZE
    RigidBodyRender.instance = this
    // 创建引擎
    this.engine = Matter.Engine.create()
    this.rigidBodies = []
    // 创建地板
    const groundWidth = CONFIG_SIZE.bgImg.width - CONFIG_SIZE.hole.width
    this.groundLeft = Matter.Bodies.rectangle(
      groundWidth / 4 + CONFIG_SIZE.holeAndRodOffset,
      CONFIG_SIZE.bgImg.height - CONFIG_SIZE.groundHeight / 2,
      groundWidth / 2,
      CONFIG_SIZE.groundHeight,
      {
        isStatic: true,
        label: 'groundLeft'
      }
    )
    this.groundRight = Matter.Bodies.rectangle(
      (groundWidth * 3) / 4 + CONFIG_SIZE.hole.width,
      CONFIG_SIZE.bgImg.height - CONFIG_SIZE.groundHeight / 2,
      groundWidth / 2,
      CONFIG_SIZE.groundHeight,
      {
        isStatic: true,
        label: 'groundRight'
      }
    )
    this.leftWall = Matter.Bodies.rectangle(
      CONFIG_SIZE.wallWidth,
      CONFIG_SIZE.bgImg.height / 2,
      CONFIG_SIZE.wallWidth,
      CONFIG_SIZE.bgImg.height,
      {
        isStatic: true,
        label: 'leftWall'
      }
    )
    this.rightWall = Matter.Bodies.rectangle(
      CONFIG_SIZE.bgImg.width - CONFIG_SIZE.wallWidth / 2,
      CONFIG_SIZE.bgImg.height / 2,
      CONFIG_SIZE.wallWidth,
      CONFIG_SIZE.bgImg.height,
      {
        isStatic: true,
        label: 'rightWall'
      }
    )
    this.holeLeft = Matter.Bodies.rectangle(
      CONFIG_SIZE.bgImg.width / 2 -
        CONFIG_SIZE.hole.width / 2 +
        CONFIG_SIZE.holeAndRodOffset +
        CONFIG_SIZE.wallWidth,
      CONFIG_SIZE.bgImg.height - CONFIG_SIZE.hole.height / 2,
      CONFIG_SIZE.wallWidth,
      CONFIG_SIZE.hole.height,
      {
        isStatic: true,
        label: 'holeLeft'
      }
    )
    this.holeRight = Matter.Bodies.rectangle(
      CONFIG_SIZE.bgImg.width / 2 + CONFIG_SIZE.hole.width / 2,
      CONFIG_SIZE.bgImg.height - CONFIG_SIZE.hole.height / 2,
      CONFIG_SIZE.wallWidth,
      CONFIG_SIZE.hole.height,
      {
        isStatic: true,
        label: 'holeLeft'
      }
    )
    Matter.World.add(this.engine.world, [
      this.groundLeft,
      this.groundRight,
      this.leftWall,
      this.rightWall,
      this.holeLeft,
      this.holeRight
    ])
    this.bodyOutsideWorld = null // 超出舞台的物体回调函数
  }
  /**
   * @description:
   * @param {RigidBody} rigidBody
   * @return {*}
   */
  addRigidBody(rigidBody) {
    this.rigidBodies.push(rigidBody)
    this.addBody(rigidBody.body)
  }
  addBody(body) {
    Matter.World.add(this.engine.world, body)
  }
  /**
   * @description:
   * @return {*}
   */
  run() {
    Matter.Engine.run(this.engine)
    PixiApp.ticker.add(() => {
      this.runLoop()
    })
  }
  runLoop() {
    this.rigidBodies.forEach((item) => {
      item.loopFunction(this.bodyOutsideWorld)
    })
  }
  /**
   * @description:
   * @param {RigidBody} rigidBody
   * @return {*}
   */
  removeRigidBody(rigidBody) {
    this.rigidBodies.splice(this.rigidBodies.indexOf(rigidBody), 1)
    this.removeBody(rigidBody.body)
  }
  /**
   * @description:
   * @param {Matter.Body} body
   * @return {*}
   */
  removeBody(body) {
    Matter.World.remove(this.engine.world, body)
  }
}
